package org.example.rabbitmqtest.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * 测试direct交换机模式
 * 使用于工作队列模式：一个生产者一个消费者或者一个生产者多个消费者
 */
//@Configuration
//public class RabbitConfiguration {
//
//    @Resource
//    private CachingConnectionFactory connectionFactory;
//
//    @Bean(name = "listenerContainer")
//    public SimpleRabbitListenerContainerFactory listenerContainer(){
//        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
//        factory.setConnectionFactory(connectionFactory);
//        factory.setPrefetchCount(1);   //将PrefetchCount设定为1表示一次只能取一个
//        return factory;
//    }
//
//    @Bean("directExchange")  //定义交换机Bean，可以很多个
//    public Exchange exchange(){
//        return ExchangeBuilder.directExchange("amq.direct").build();
//    }
//
//    @Bean("testQueue")     //定义消息队列
//    public Queue queue(){
//        return QueueBuilder
//                .nonDurable("testQueue")   //非持久化类型
//                //.deadLetterExchange("dlx.direct")   //指定死信交换机
//                //.deadLetterRoutingKey("dl-yyds")   //指定死信RoutingKey
//                //.ttl(5000) //ttl过期时间5秒钟后未处理，发送到死信交换机对应的死信队列中
//                //.maxLength(3)
//                .build();
//    }
//
//    @Bean("binding")
//    public Binding binding(@Qualifier("directExchange") Exchange exchange,
//                           @Qualifier("testQueue") Queue queue){
//        //将我们刚刚定义的交换机和队列进行绑定
//        return BindingBuilder
//                .bind(queue)   //绑定队列
//                .to(exchange)  //到交换机
//                .with("MyTestQueue")   //使用自定义的routingKey
//                .noargs();
//    }
//
////    @Bean("jacksonConverter")
////    public Jackson2JsonMessageConverter converter(){
////        return new Jackson2JsonMessageConverter();
////    }
////
////
////    @Bean("directDlExchange")
////    public Exchange dlExchange(){
////        //创建一个新的死信交换机
////        return ExchangeBuilder.directExchange("dlx.direct").build();
////    }
////
////    @Bean("testDlQueue")   //创建一个新的死信队列
////    public Queue dlQueue(){
////        return QueueBuilder
////                .nonDurable("dl_queue")
////                .build();
////    }
////
////    @Bean("dlBinding")   //死信交换机和死信队列进绑定
////    public Binding dlBinding(@Qualifier("directDlExchange") Exchange exchange,
////                             @Qualifier("testDlQueue") Queue queue){
////        return BindingBuilder
////                .bind(queue)
////                .to(exchange)
////                .with("dl-yyds")
////                .noargs();
////    }
//}

/**
 * fanout交换机类型
 * 发布订阅模式 发布一次，消费多个
 */
//@Configuration
//public class RabbitConfiguration {
//
//    @Bean("fanoutExchange")
//    public Exchange exchange(){
//        //注意这里是fanoutExchange
//        return ExchangeBuilder.fanoutExchange("amq.fanout").build();
//    }
//
//    @Bean("yydsQueue1")
//    public Queue queue(){
//        return QueueBuilder.nonDurable("yyds1").build();
//    }
//
//    @Bean("binding")
//    public Binding binding(@Qualifier("fanoutExchange") Exchange exchange,
//                           @Qualifier("yydsQueue1") Queue queue){
//        return BindingBuilder
//                .bind(queue)
//                .to(exchange)
//                .with("yyds1")
//                .noargs();
//    }
//
//    @Bean("yydsQueue2")
//    public Queue queue2(){
//        return QueueBuilder.nonDurable("yyds2").build();
//    }
//
//    @Bean("binding2")
//    public Binding binding2(@Qualifier("fanoutExchange") Exchange exchange,
//                            @Qualifier("yydsQueue2") Queue queue){
//        return BindingBuilder
//                .bind(queue)
//                .to(exchange)
//                .with("yyds2")
//                .noargs();
//    }
//}

//路由模式
//我们可以在绑定时指定想要的routingKey只有生产者发送时指定了对应的routingKey才能到达对应的队列。
//@Configuration
//public class RabbitConfiguration {
//
//    @Bean("directExchange")
//    public Exchange exchange(){
//        return ExchangeBuilder.directExchange("amq.direct").build();
//    }
//
//    @Bean("yydsQueue")
//    public Queue queue(){
//        return QueueBuilder.nonDurable("yyds").build();
//    }
//
//    @Bean("binding")   //使用yyds1绑定
//    public Binding binding(@Qualifier("directExchange") Exchange exchange,
//                           @Qualifier("yydsQueue") Queue queue){
//        return BindingBuilder
//                .bind(queue)
//                .to(exchange)
//                .with("yyds1")
//                .noargs();
//    }
//
//    @Bean("binding2")   //使用yyds2绑定
//    public Binding binding2(@Qualifier("directExchange") Exchange exchange,
//                            @Qualifier("yydsQueue") Queue queue){
//        return BindingBuilder
//                .bind(queue)
//                .to(exchange)
//                .with("yyds2")
//                .noargs();
//    }
//}

/**
 * 主题模式
 *
 *  这种模式就是一种模糊匹配的模式，我们可以将routingKey以模糊匹配的方式去进行转发
 */

//我们可以使用*或#来表示：
// * - 表示任意的一个单词
// # - 表示0个或多个单词
//@Configuration
//public class RabbitConfiguration {
//
//    @Bean("topicExchange")  //这里使用预置的Topic类型交换机
//    public Exchange exchange(){
//        return ExchangeBuilder.topicExchange("amq.topic").build();
//    }
//
//    @Bean("yydsQueue")
//    public Queue queue(){
//        return QueueBuilder.nonDurable("yyds").build();
//    }
//
//    @Bean("binding")
//    public Binding binding2(@Qualifier("topicExchange") Exchange exchange,
//                            @Qualifier("yydsQueue") Queue queue){
//        return BindingBuilder
//                .bind(queue)
//                .to(exchange)
//                .with("*.test.*")
//                .noargs();
//    }
//}

//header交换机类型
@Configuration
public class RabbitConfiguration {

    @Bean("headerExchange")  //注意这里返回的是HeadersExchange
    public HeadersExchange exchange(){
        return ExchangeBuilder
                .headersExchange("amq.headers")  //RabbitMQ为我们预置了两个，这里用第一个就行
                .build();
    }

    @Bean("yydsQueue")
    public Queue queue(){
        return QueueBuilder.nonDurable("yyds").build();
    }

    @Bean("binding")
    public Binding binding2(@Qualifier("headerExchange") HeadersExchange exchange,  //这里和上面一样的类型
                            @Qualifier("yydsQueue") Queue queue){
        return BindingBuilder
                .bind(queue)
                .to(exchange)   //使用HeadersExchange的to方法，可以进行进一步配置
                //.whereAny("a", "b").exist();   这个是只要存在任意一个指定的头部Key就行
                //.whereAll("a", "b").exist();   这个是必须存在所有指定的的头部Key
                .where("test").matches("hello");   //比如我们现在需要消息的头部信息中包含test，并且值为hello才能转发给我们的消息队列
        //.whereAny(Collections.singletonMap("test", "hello")).match();  传入Map也行，批量指定键值对
    }
}